package com.evan.common.scheduleTask;

import com.evan.common.bit.ZkServerModeEnum;
import com.evan.common.bit.ZkServerStatus;
import com.evan.common.pojo.Cluster;
import com.evan.common.pojo.ZkServerInfo;
import com.evan.common.service.ClusterService;
import com.evan.common.service.ZkServerService;
import com.evan.common.utils.SocketClient;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.ConnectException;
import java.util.*;

@Component
public class SchedulerTask {

    @Autowired
    ZkServerService zkService;
    @Autowired
    ClusterService cService;
    private static final Integer TIMEOUT = 30000;

//    @Scheduled(cron = "*/30 * * * *")
    @Scheduled(fixedDelay = 3000) // 3s
    public void zkHeartbeat() throws Exception {

        // 集群ID
        Integer cid = 1; // default cluster

        cService.getAllCluster();
        updateZkStat(cid);


    }

    public void updateZkStat(Integer cid){
        List<String> anyZkInfo = new ArrayList<>();
        ObjectMapper objectSer = new ObjectMapper();

        Cluster cluster = cService.getClusterByCid(cid).get();

        // 获取默认集群
        String clusterJson = null;
        try {
            clusterJson = objectSer.writeValueAsString(cluster);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        System.out.println(clusterJson);


        // 获取默认集群中zookeeper服务的状态，获取到状态即服务在线，否则离线
        List<ZkServerInfo> zkServers = zkService.getZkNodeByClusterId(cid);
        for (ZkServerInfo zkServer : zkServers) {
            SocketClient socketClient = null;
            try {
                socketClient = new SocketClient(zkServer.getIp(), zkServer.getPort());
            } catch (ConnectException e){
                zkService.updateStat(zkServer.getZid()
                        , ZkServerModeEnum.UNKNOWN
                        , ZkServerStatus.OFFLINE);
            } catch (IOException e) {
                e.printStackTrace();
            }
            String stat;
            try {
                if(socketClient != null) {
                stat = socketClient.sendStat();

                    if (stat.equals("leader")) {
                        zkServer.setServerMode(ZkServerModeEnum.LEADER);
                    } else {
                        zkServer.setServerMode(ZkServerModeEnum.FOLLOWER);
                    }
                    zkService.updateStat(zkServer.getZid()
                            , zkServer.getServerMode()
                            , ZkServerStatus.ONLINE);
                }
            } catch (IOException e) {
                zkService.updateStat(zkServer.getZid()
                        , ZkServerModeEnum.UNKNOWN
                        , ZkServerStatus.UNKNOWN);
            }

            ObjectMapper objectMapper = new ObjectMapper();
            String zkServerJson = null;
            try {
                zkServerJson = objectMapper.writeValueAsString(zkServer);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            anyZkInfo.add(zkServerJson);
        }

        System.out.println(anyZkInfo);
    }

    public Map<String, List<ZkServerInfo>> getZkInfoInCluster(Integer cid){
        Map<String,List<ZkServerInfo>> os = new HashMap<>();
        Optional<Cluster> cluster = cService.getClusterByCid(cid);
        List<ZkServerInfo> nodeByClusterId = zkService.getZkNodeByClusterId(cid);
        os.put(cluster.get().getClusterName(),nodeByClusterId);
        return os;
    }


}
